package com.leyou.cart.service;

import com.leyou.cart.entity.Cart;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.threadlocals.UserHolder;
import com.leyou.common.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @package com.leyou.cart.service
 * @description: 购物车业务层
 * @author: 许超越
 * @date 2019/7/10 21:08
 * @version: V1.0
 */
@Service
@Slf4j
public class CartService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String KEY_PREFIX = "ly:cart:uid:";


    /**
     * 购物车添加商品
     * @param cart
     * @return
     */
    public void addCart(Cart cart) {
        //获取当前用户
        String key = KEY_PREFIX + UserHolder.getUser().getId();
        //后去hash的类型，并绑定了id的值
        BoundHashOperations<String, String, String> hashOps = redisTemplate.boundHashOps(key);
        addCartInRedis(cart, hashOps);
    }

    /**
     * 将商品添加到Redis中
     * @param cart
     * @param hashOps
     */
    private void addCartInRedis(Cart cart, BoundHashOperations<String, String, String> hashOps) {
        //获取商品的id，作为hashOps的值得key
        String skuId = cart.getSkuId().toString();
        //判断原来的集合中是否存在同样的key
        Boolean bool = hashOps.hasKey(skuId);
        if (bool != null && bool) {
            //Redis中存在该商品了，修改商品数量-
            Cart cacheCart = JsonUtils.toBean(hashOps.get(skuId), Cart.class);
            cacheCart.setNum(cart.getNum() + cacheCart.getNum());
            // 写回redis
            hashOps.put(skuId, JsonUtils.toString(cacheCart));
        }else {
            // 写入redis
            hashOps.put(skuId, JsonUtils.toString(cart));
        }
    }


    /**
     * 查询用户的购物车
     * @return
     */
    public List<Cart> queryCartList() {
        //获取当前用户的Redis中的key
        String key = KEY_PREFIX + UserHolder.getUser().getId();
        //判断购物车是否存在
        Boolean bool = redisTemplate.hasKey(key);
        if (bool == null || !bool) {
            //没有购物车
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }
        //存在购物车
        BoundHashOperations<String, String, String> hashOps = redisTemplate.boundHashOps(key);
        //判断是否存在商品
        Long size = hashOps.size();
        if (size == null || size <= 0) {
            //不存在货物
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }
        //获取所有的商品信息
        List<String> carts = hashOps.values();
        //处理商品信息返回
        assert carts != null;
        return carts.stream().map(cartJson -> JsonUtils.toBean(cartJson, Cart.class)).collect(Collectors.toList());
    }


    /**
     * 修改当前用户的购物车的商品数量
     * @param skuId 商品skuId
     * @param num 修改后商品的数量
     */
    public void updateCartNum(Long skuId, Integer num) {
        //获取当前用户购物车在Redis中的key
        String key = KEY_PREFIX + UserHolder.getUser().getId();
        //获取hashOps操作对象
        BoundHashOperations<String, String, String> hashOps = redisTemplate.boundHashOps(key);
        //获取操作的hashKey
        String hashKey = skuId.toString();
        //判断是否存在此商品
        Boolean bool = hashOps.hasKey(hashKey);
        if (bool == null || !bool) {
            log.error("购物车商品不存在，用户：{}，商品：{}", UserHolder.getUser().getId(), skuId);
            throw new LyException(ExceptionEnum.CARTS_NOT_FOUND);
        }
        //获取购物车里的商品
        Cart cart = JsonUtils.toBean(hashOps.get(hashKey), Cart.class);
        //修改商品的数量
        cart.setNum(num);
        //写回Redis
        hashOps.put(hashKey, JsonUtils.toString(cart));
    }


    /**
     * 删除购物车中的商品
     * @param skuId 商品的id
     */
    public void deleteCart(String skuId) {
        //获取key
        String key = KEY_PREFIX + UserHolder.getUser().getId();
        //删除
        redisTemplate.opsForHash().delete(key, skuId);
    }


    /**
     * 批量新增未登入添加的购物车商品
     * @param cartList
     */
    public void addCartList(List<Cart> cartList) {
        //获取当前用户购物车的key
        String key = KEY_PREFIX + UserHolder.getUser().getId();
        //获取操作商品的对象
        BoundHashOperations<String, String, String> hashOps = redisTemplate.boundHashOps(key);
        //添加商品
        cartList.forEach(cart -> addCartInRedis(cart, hashOps));
    }


    /**
     * 批量删除购物车中的商品
     * @param skuIdList
     */
    public void deleteCartByIds(List<Long> skuIdList, String userId) {
        //获取key
        String key = KEY_PREFIX + userId;
        //获取删除操作对象
        HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
        //批量删除
        skuIdList.forEach(skuId -> hashOps.delete(key, skuId.toString()));
    }
}
